<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>WebSocket 端口扫描器</title>
  <style>
    /* 基础样式设置 */
    body { font-family: sans-serif; padding: 1rem; }
    input, button { margin: 0.5rem 0; }
    #output { white-space: pre; background: #f5f5f5; padding: 1rem; border-radius: 4px; }
  </style>
</head>
<body>
<!-- 界面元素 -->
  <h2>WebSocket 端口扫描器</h2>
  <label>Host: <input id="host" value="127.0.0.1" /></label><br />
  <label>From Port: <input id="from" type="number" value="1" /></label><br />
  <label>To Port: <input id="to" type="number" value="1024" /></label><br />
  <button id="startBtn">开始扫描</button>
  <div id="output"></div>

  <script>
    // 绑定开始按钮点击事件
    document.getElementById('startBtn').addEventListener('click', () => {
      // 获取输入值
      const host = document.getElementById('host').value.trim();
      const fromPort = parseInt(document.getElementById('from').value, 10);
      const toPort   = parseInt(document.getElementById('to').value, 10);
      const outputEl = document.getElementById('output');
      outputEl.textContent = '';// 清空之前的结果
      // 输入验证流程
      if (!isValidHost(host)) {
          showError('无效的IP/域名格式');
          return;
      }
      if (isNaN(fromPort) || isNaN(toPort) || fromPort < 1 || toPort > 65535 || fromPort > toPort) {
          showError('端口范围应为1-65535且From Port ≤ To Port');
          return;
      }

      // 创建WebSocket连接
      const ws = new WebSocket('ws://localhost:8025/portscan');
      // WebSocket事件处理器
      ws.onopen = () => {
        // 发送扫描请求（JSON格式）
        ws.send(JSON.stringify({ host, fromPort, toPort }));
        outputEl.textContent += `已发送扫描请求：${host} [${fromPort}–${toPort}]\n`;
      };
      ws.onmessage = evt => {
        // 解析服务器返回的扫描结果
        const { port, open } = JSON.parse(evt.data);
        outputEl.textContent += `Port ${port}: ${open ? '✅ 开放' : '❌ 关闭'}\n`;
      };
      ws.onerror = err => {
        outputEl.textContent += `⚠️ 连接或扫描出错：${err.message || err}\n`;
      };
      ws.onclose = () => {
        outputEl.textContent += '扫描完成，连接已关闭。\n';
      };
    });

    //验证主机名格式
    function isValidHost(host) {
        const ipPattern = /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/;
        const domainPattern = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i;
        return ipPattern.test(host) || domainPattern.test(host);
    }

    //显示错误信息
    function showError(msg) {
        const outputEl = document.getElementById('output');
        outputEl.textContent += `❌ 错误: ${msg}\n`;
        isScanning = false;
        if (ws) ws.close();
    }

  </script>
</body>
</html>
